package com.sq.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * 摘要：日期工具类
 */
public class DateUtil {
    private static final int[] dayArray = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    private static SimpleDateFormat sdf = new SimpleDateFormat();

    public static final String formatDefaultTimestamp = "yyyy-MM-dd HH:mm:ss";
    public static final String format_yyyy_MM_dd_HHmmssSSS = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String format_yyyy_MM_dd_HHmmss = "yyyy-MM-dd HH:mm:ss";
    public static final String format_yyyy_MM_dd_HHmm = "yyyy-MM-dd HH:mm";
    public static final String format_yyyy_MM_dd_HH = "yyyy-MM-dd HH";
    public static final String format_yyyyMMddHHmm = "yyyyMMddHHmm";
    public static final String format_yyyyMMdd = "yyyyMMdd";
    public static final String format_yyyyMM = "yyyyMM";
    public static final String format_yyyy = "yyyy";
    public static final String format_MM_dd_HHmm = "MM-dd HH:mm";
    public static final String format_yyyy_MM_dd = "yyyy-MM-dd";
    public static final String format_yyyyMMddHHmmss = "yyyyMMddHHmmss";
    public static final String format_yyyy年MM月dd日 = "yyyy年MM月dd日";
    public static final String format_yyyyMMdd_bias = "yyyy/MM/dd";
    public static final String format_yyyyMMddhhmmss_bias = "yyyy/MM/dd HH:mm:ss";
    public static final String format_yyyyMMdd_bias_mmdd = "MM/dd";
    public static final String format_HHMM = "HH:mm";

    public static synchronized Calendar getCalendar() {
        return GregorianCalendar.getInstance();
    }

    /**
     * @return String
     */
    public static synchronized String getDateMilliFormat() {
        Calendar cal = Calendar.getInstance();
        return getDateMilliFormat(cal);
    }

    /**
     * @param cal
     * @return String
     */
    public static synchronized String getDateMilliFormat(Calendar cal) {
        String pattern = "yyyy-MM-dd HH:mm:ss,SSS";
        return getDateFormat(cal, pattern);
    }

    /**
     * @param date
     * @return String
     */
    public static synchronized String getDateMilliFormat(Date date) {
        String pattern = "yyyy-MM-dd HH:mm:ss,SSS";
        return getDateFormat(date, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Calendar
     */
    public static synchronized Calendar parseCalendarMilliFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm:ss,SSS";
        return parseCalendarFormat(strDate, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Date
     */
    public static synchronized Date parseDateMilliFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm:ss,SSS";
        return parseDateFormat(strDate, pattern);
    }

    /**
     * @return String
     */
    public static synchronized String getDateSecondFormat() {
        Calendar cal = Calendar.getInstance();
        return getDateSecondFormat(cal);
    }

    /**
     * @param cal
     * @return String
     */
    public static synchronized String getDateSecondFormat(Calendar cal) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return getDateFormat(cal, pattern);
    }

    /**
     * @param date
     * @return String
     */
    public static synchronized String getDateSecondFormat(Date date) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return getDateFormat(date, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Calendar
     */
    public static synchronized Calendar parseCalendarSecondFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return parseCalendarFormat(strDate, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Date
     */
    public static synchronized Date parseDateSecondFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return parseDateFormat(strDate, pattern);
    }

    /**
     * 功能：获取yyyyMMddHHmmss格式字符串
     */
    public final static String toYyyymmddHhmmss() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(new Date());
    }

    /**
     * 功能：获取ddHHmmss格式字符串
     */
    public final static String toddHhmmss() {
        SimpleDateFormat sdf = new SimpleDateFormat("ddHHmmss");
        return sdf.format(new Date());
    }

    /**
     * @return String
     */
    public static synchronized String getDateMinuteFormat() {
        Calendar cal = Calendar.getInstance();
        return getDateMinuteFormat(cal);
    }

    /**
     * @param date
     * @return date
     */
    public static synchronized Date getPreviousDay(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, -1);
        return gc.getTime();
    }

    public static synchronized String getYear() {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        String year = Integer.toString(gc.get(Calendar.YEAR));
        return year;
    }

    /**
     * @param cal
     * @return String
     */
    public static synchronized String getDateMinuteFormat(Calendar cal) {
        String pattern = "yyyy-MM-dd HH:mm";
        return getDateFormat(cal, pattern);
    }

    /**
     * @param date
     * @return String
     */
    public static synchronized String getDateMinuteFormat(Date date) {
        String pattern = "yyyy-MM-dd HH:mm";
        return getDateFormat(date, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Calendar
     */
    public static synchronized Calendar parseCalendarMinuteFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm";
        return parseCalendarFormat(strDate, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Date
     */
    public static synchronized Date parseDateMinuteFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm";
        return parseDateFormat(strDate, pattern);
    }

    /**
     * @return String
     */
    public static synchronized String getDateDayFormat() {
        Calendar cal = Calendar.getInstance();
        return getDateDayFormat(cal);
    }

    /**
     * @param cal
     * @return String
     */
    public static synchronized String getDateDayFormat(Calendar cal) {
        String pattern = "yyyy-MM-dd";
        return getDateFormat(cal, pattern);
    }

    /**
     * 将日期转为yyyy-MM-dd 字符串
     */
    public static synchronized String getDateDayFormat(Date date) {
        String pattern = "yyyy-MM-dd";
        return getDateFormat(date, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Calendar
     */
    public static synchronized Calendar parseCalendarDayFormat(String strDate) {
        String pattern = "yyyy-MM-dd";
        return parseCalendarFormat(strDate, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Date
     */
    public static synchronized Date parseDateDayFormat(String strDate) {
        String pattern = "yyyy-MM-dd";
        return parseDateFormat(strDate, pattern);
    }

    /**
     * @return String
     */
    public static synchronized String getDateFileFormat() {
        Calendar cal = Calendar.getInstance();
        return getDateFileFormat(cal);
    }

    /**
     * @param cal
     * @return String
     */
    public static synchronized String getDateFileFormat(Calendar cal) {
        String pattern = "yyyy-MM-dd_HH-mm-ss";
        return getDateFormat(cal, pattern);
    }

    /**
     * @param date
     * @return String
     */
    public static synchronized String getDateFileFormat(Date date) {
        String pattern = "yyyy-MM-dd_HH-mm-ss";
        return getDateFormat(date, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Calendar
     */
    public static synchronized Calendar parseCalendarFileFormat(String strDate) {
        String pattern = "yyyy-MM-dd_HH-mm-ss";
        return parseCalendarFormat(strDate, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Date
     */
    public static synchronized Date parseDateFileFormat(String strDate) {
        String pattern = "yyyy-MM-dd_HH-mm-ss";
        return parseDateFormat(strDate, pattern);
    }

    /**
     * @return String
     */
    public static synchronized String getDateW3CFormat() {
        Calendar cal = Calendar.getInstance();
        return getDateW3CFormat(cal);
    }

    /**
     * @param cal
     * @return String
     */
    public static synchronized String getDateW3CFormat(Calendar cal) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return getDateFormat(cal, pattern);
    }

    /**
     * @param date
     * @return String
     */
    public static synchronized String getDateW3CFormat(Date date) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return getDateFormat(date, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Calendar
     */
    public static synchronized Calendar parseCalendarW3CFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return parseCalendarFormat(strDate, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Date
     */
    public static synchronized Date parseDateW3CFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return parseDateFormat(strDate, pattern);
    }

    /**
     * @param cal
     * @return String
     */
    public static synchronized String getDateFormat(Calendar cal) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return getDateFormat(cal, pattern);
    }

    /**
     * @param date
     * @return String
     */
    public static synchronized String getDateFormat(Date date) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return getDateFormat(date, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Calendar
     */
    public static synchronized Calendar parseCalendarFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return parseCalendarFormat(strDate, pattern);
    }

    /**
     * @param strDate
     * @return java.util.Date
     */
    public static synchronized Date parseDateFormat(String strDate) {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return parseDateFormat(strDate, pattern);
    }

    /**
     * @param cal
     * @param pattern
     * @return String
     */
    public static synchronized String getDateFormat(Calendar cal, String pattern) {
        return getDateFormat(cal.getTime(), pattern);
    }

    /**
     * @param date
     * @param pattern
     * @return String
     */
    public static synchronized String getDateFormat(Date date, String pattern) {
        synchronized (sdf) {
            String str = null;
            sdf.applyPattern(pattern);
            str = sdf.format(date);
            return str;
        }
    }

    /**
     * @param strDate
     * @param pattern
     * @return java.util.Calendar
     */
    public static synchronized Calendar parseCalendarFormat(String strDate, String pattern) {
        synchronized (sdf) {
            Calendar cal = null;
            sdf.applyPattern(pattern);
            try {
                sdf.parse(strDate);
                cal = sdf.getCalendar();
            } catch (Exception e) {
            }
            return cal;
        }
    }

    /**
     * @param strDate
     * @param pattern
     * @return java.util.Date
     */
    public static synchronized Date parseDateFormat(String strDate, String pattern) {
        synchronized (sdf) {
            Date date = null;
            sdf.applyPattern(pattern);
            try {
                date = sdf.parse(strDate);
            } catch (Exception e) {
            }
            return date;
        }
    }

    public static synchronized int getLastDayOfMonth(int month) {
        if (month < 1 || month > 12) {
            return -1;
        }
        int retn = 0;
        if (month == 2) {
            if (isLeapYear()) {
                retn = 29;
            } else {
                retn = dayArray[month - 1];
            }
        } else {
            retn = dayArray[month - 1];
        }
        return retn;
    }

    public static synchronized int getLastDayOfMonth(int year, int month) {
        if (month < 1 || month > 12) {
            return -1;
        }
        int retn = 0;
        if (month == 2) {
            if (isLeapYear(year)) {
                retn = 29;
            } else {
                retn = dayArray[month - 1];
            }
        } else {
            retn = dayArray[month - 1];
        }
        return retn;
    }

    public static synchronized int getDayOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK);
    }

    public static synchronized boolean isLeapYear() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        return isLeapYear(year);
    }

    public static synchronized boolean isLeapYear(int year) {
        if ((year % 400) == 0)
            return true;
        else if ((year % 4) == 0) {
            if ((year % 100) == 0)
                return false;
            else
                return true;
        } else
            return false;
    }

    public static synchronized boolean isLeapYear(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        int year = gc.get(Calendar.YEAR);
        return isLeapYear(year);
    }

    public static synchronized boolean isLeapYear(Calendar gc) {
        int year = gc.get(Calendar.YEAR);
        return isLeapYear(year);
    }

    public static synchronized Date getPreviousWeekDay(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return getPreviousWeekDay(gc);
    }

    public static synchronized Date getPreviousWeekDay(Calendar gc) {
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, -3);
                break;
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, -2);
                break;
            default:
                gc.add(Calendar.DATE, -1);
                break;
        }
        return gc.getTime();
    }

    public static synchronized Date getNextWeekDay(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, 3);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, 2);
                break;
            default:
                gc.add(Calendar.DATE, 1);
                break;
        }
        return gc.getTime();
    }

    public static synchronized Calendar getNextWeekDay(Calendar gc) {
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, 3);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, 2);
                break;
            default:
                gc.add(Calendar.DATE, 1);
                break;
        }
        return gc;
    }

    public static synchronized boolean isTodaySaturday(Date today) {
        Calendar gc = Calendar.getInstance();
        gc.setTime(today);
        if (gc.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            return true;
        }
        return false;
    }

    public static synchronized boolean isTodaySaturday() {
        Calendar gc = Calendar.getInstance();
        if (gc.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            return true;
        }
        return false;
    }

    public static synchronized Date getLastDayOfNextMonth(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.setTime(getNextMonth(gc.getTime()));
        gc.setTime(getLastDayOfMonth(gc.getTime()));
        return gc.getTime();
    }

    public static synchronized Date getLastDayOfNextWeek(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.setTime(getNextWeek(gc.getTime()));
        gc.setTime(getLastDayOfWeek(gc.getTime()));
        return gc.getTime();
    }

    public static synchronized Date getFirstDayOfNextMonth(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.setTime(getNextMonth(gc.getTime()));
        gc.setTime(getFirstDayOfMonth(gc.getTime()));
        return gc.getTime();
    }

    public static synchronized Calendar getFirstDayOfNextMonth(Calendar gc) {
        gc.setTime(getNextMonth(gc.getTime()));
        gc.setTime(getFirstDayOfMonth(gc.getTime()));
        return gc;
    }

    public static synchronized Date getFirstDayOfNextWeek(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.setTime(getNextWeek(gc.getTime()));
        gc.setTime(getFirstDayOfWeek(gc.getTime()));
        return gc.getTime();
    }

    public static synchronized Calendar getFirstDayOfNextWeek(Calendar gc) {
        gc.setTime(getNextWeek(gc.getTime()));
        gc.setTime(getFirstDayOfWeek(gc.getTime()));
        return gc;
    }

    public static synchronized Date getLastMonth(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.MONTH, -1);
        return gc.getTime();
    }

    public static synchronized Date getLastMonth(Date date, int n) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.MONTH, -n);
        return gc.getTime();
    }

    public static synchronized Calendar getLastMonth(Calendar gc) {
        gc.add(Calendar.MONTH, -1);
        return gc;
    }

    public static synchronized Date getNextMonth(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.MONTH, 1);
        return gc.getTime();
    }

    public static synchronized Calendar getNextMonth(Calendar gc) {
        gc.add(Calendar.MONTH, 1);
        return gc;
    }

    public static synchronized Date getNextDay(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, 1);
        return gc.getTime();
    }

    public static synchronized Calendar getNextDay(Calendar gc) {
        gc.add(Calendar.DATE, 1);
        return gc;
    }

    public static synchronized Date getPreviousWeek(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, -7);
        return gc.getTime();
    }

    public static synchronized Calendar getPreviousWeek(Calendar gc) {
        gc.add(Calendar.DATE, -7);
        return gc;
    }

    public static synchronized Date getNextWeek(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, 7);
        return gc.getTime();
    }

    public static synchronized Calendar getNextWeek(Calendar gc) {
        gc.add(Calendar.DATE, 7);
        return gc;
    }

    public static synchronized Date getLastDayOfWeek(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, 6);
                break;
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, 5);
                break;
            case (Calendar.TUESDAY):
                gc.add(Calendar.DATE, 4);
                break;
            case (Calendar.WEDNESDAY):
                gc.add(Calendar.DATE, 3);
                break;
            case (Calendar.THURSDAY):
                gc.add(Calendar.DATE, 2);
                break;
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, 1);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, 0);
                break;
        }
        return gc.getTime();
    }

    public static synchronized Date getFirstDayOfWeek(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, 0);
                break;
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, -1);
                break;
            case (Calendar.TUESDAY):
                gc.add(Calendar.DATE, -2);
                break;
            case (Calendar.WEDNESDAY):
                gc.add(Calendar.DATE, -3);
                break;
            case (Calendar.THURSDAY):
                gc.add(Calendar.DATE, -4);
                break;
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, -5);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, -6);
                break;
        }
        return gc.getTime();
    }

    public static synchronized Calendar getFirstDayOfWeek(Calendar gc) {
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, 0);
                break;
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, -1);
                break;
            case (Calendar.TUESDAY):
                gc.add(Calendar.DATE, -2);
                break;
            case (Calendar.WEDNESDAY):
                gc.add(Calendar.DATE, -3);
                break;
            case (Calendar.THURSDAY):
                gc.add(Calendar.DATE, -4);
                break;
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, -5);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, -6);
                break;
        }
        return gc;
    }

    public static synchronized Date getLastDayOfMonth(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        switch (gc.get(Calendar.MONTH)) {
            case 0:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 1:
                gc.set(Calendar.DAY_OF_MONTH, 28);
                break;
            case 2:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 3:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 4:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 5:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 6:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 7:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 8:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 9:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 10:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 11:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
        }
        // �������
        if ((gc.get(Calendar.MONTH) == Calendar.FEBRUARY) && (isLeapYear(gc.get(Calendar.YEAR)))) {
            gc.set(Calendar.DAY_OF_MONTH, 29);
        }
        return gc.getTime();
    }

    public static synchronized Calendar getLastDayOfMonth(Calendar gc) {
        switch (gc.get(Calendar.MONTH)) {
            case 0:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 1:
                gc.set(Calendar.DAY_OF_MONTH, 28);
                break;
            case 2:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 3:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 4:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 5:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 6:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 7:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 8:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 9:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 10:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 11:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
        }
        if ((gc.get(Calendar.MONTH) == Calendar.FEBRUARY) && (isLeapYear(gc.get(Calendar.YEAR)))) {
            gc.set(Calendar.DAY_OF_MONTH, 29);
        }
        return gc;
    }

    public static synchronized Date getFirstDayOfMonth(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.set(Calendar.DAY_OF_MONTH, 1);
        return gc.getTime();
    }

    public static synchronized Calendar getFirstDayOfMonth(Calendar gc) {
        /**
         * ��ϸ��ƣ� 1.����Ϊ1��
         */
        gc.set(Calendar.DAY_OF_MONTH, 1);
        return gc;
    }

    public static synchronized String toOraString(Date theDate, boolean hasTime) {
        DateFormat theFormat;
        if (hasTime) {
            theFormat = getOraDateTimeFormat();
        } else {
            theFormat = getOraDateFormat();
        }
        return toString(theDate, theFormat);
    }

    public static synchronized String toString(Date theDate, boolean hasTime) {
        DateFormat theFormat;
        if (hasTime) {
            theFormat = getDateTimeFormat();
        } else {
            theFormat = getDateFormat();
        }
        return toString(theDate, theFormat);
    }

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
    private static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm");
    @SuppressWarnings("unused")
    private static final SimpleDateFormat DATE_TIME_EXTENDED_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    private static final SimpleDateFormat ORA_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
    private static final SimpleDateFormat ORA_DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMddHHmm");

    @SuppressWarnings("unused")
    private static final SimpleDateFormat ORA_DATE_TIME_EXTENDED_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");

    public static synchronized DateFormat getDateFormat_ORA_DATE_TIME_EXTENDED() {
        SimpleDateFormat theDateFormat = (SimpleDateFormat) DATE_FORMAT.clone();
        theDateFormat.setLenient(false);
        return theDateFormat;
    }

    public static synchronized DateFormat getDateFormat() {
        SimpleDateFormat theDateFormat = (SimpleDateFormat) DATE_FORMAT.clone();
        theDateFormat.setLenient(false);
        return theDateFormat;
    }

    public static synchronized DateFormat getDateTimeFormat() {
        SimpleDateFormat theDateTimeFormat = (SimpleDateFormat) DATE_TIME_FORMAT.clone();
        theDateTimeFormat.setLenient(false);
        return theDateTimeFormat;
    }

    public static synchronized DateFormat getOraDateFormat() {
        SimpleDateFormat theDateFormat = (SimpleDateFormat) ORA_DATE_FORMAT.clone();
        theDateFormat.setLenient(false);
        return theDateFormat;
    }

    public static synchronized DateFormat getOraDateTimeFormat() {
        SimpleDateFormat theDateTimeFormat = (SimpleDateFormat) ORA_DATE_TIME_FORMAT.clone();
        theDateTimeFormat.setLenient(false);
        return theDateTimeFormat;
    }

    public static synchronized Date getPreviousNDay(Date date, int n) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, n);
        return gc.getTime();
    }

    public static synchronized String toString(Date theDate, DateFormat theDateFormat) {
        if (theDate == null) {
            return "";
        }
        return theDateFormat.format(theDate);
    }

    public static String getDateByMillTime(long millSeconds) {
        Calendar gc = Calendar.getInstance();
        gc.setTimeInMillis(millSeconds * 1000 - 8 * 3600 * 1000);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(gc.getTime());
    }

    /**
     * 将秒转化为yyyy-MM-dd HH:mm:ss字符串
     *
     * @param millSeconds 秒
     */
    public static String formatSecondsTo14s(long millSeconds) {
        Calendar gc = Calendar.getInstance();
        gc.setTimeInMillis(millSeconds * 1000L);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(gc.getTime());
    }

    /**
     * 将秒转化为yyyy-MM-dd字符串
     *
     * @param millSeconds 秒
     */
    public static String formatSecondsTo8s(long millSeconds) {
        Calendar gc = Calendar.getInstance();
        gc.setTimeInMillis(millSeconds * 1000L);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(gc.getTime());
    }

    public static Date getFirstDayOfThisMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(calendar.get(GregorianCalendar.YEAR), calendar.get(GregorianCalendar.MONTH),
                calendar.get(GregorianCalendar.DATE), 0, 0, 0);
        return calendar.getTime();
    }

    public static Date getFirstDayOfNextMonth() {
        Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(GregorianCalendar.MONTH, 1);
        calendar.set(calendar.get(GregorianCalendar.YEAR), calendar.get(GregorianCalendar.MONTH),
                calendar.get(GregorianCalendar.DATE), 0, 0, 0);
        return calendar.getTime();
    }

    public static Date getYesterday() {
        Calendar calendar = GregorianCalendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        calendar.set(calendar.get(GregorianCalendar.YEAR), calendar.get(GregorianCalendar.MONTH),
                calendar.get(GregorianCalendar.DATE), 0, 0, 0);
        return calendar.getTime();
    }

    public static Date getStarSecondOfToday() {
        Calendar calendar = new GregorianCalendar();
        calendar.set(calendar.get(GregorianCalendar.YEAR), calendar.get(GregorianCalendar.MONTH),
                calendar.get(GregorianCalendar.DATE), 0, 0, 0);
        return calendar.getTime();
    }

    public static Date getLastSecondOfToday() {
        Calendar calendar = new GregorianCalendar();
        calendar.set(calendar.get(GregorianCalendar.YEAR), calendar.get(GregorianCalendar.MONTH),
                calendar.get(GregorianCalendar.DATE), 23, 59, 59);
        return calendar.getTime();
    }

    public static Date getMidDayOfThisMonthExptSunday() {
        Date today = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(GregorianCalendar.YEAR), calendar.get(GregorianCalendar.MONTH), 15, 0, 0, 0);
        int days = calendar.get(Calendar.DAY_OF_WEEK);
        if (days == 1) {
            calendar.add(Calendar.DATE, 1);
        }
        Date midMonth = calendar.getTime();
        Date clearingBeginDate = getFirstDayOfThisMonth();
        if (today.after(midMonth)) {
            clearingBeginDate = midMonth;
        }
        return clearingBeginDate;
    }

    public static Date getMaxDate() {
        Calendar calendar = new GregorianCalendar();
        calendar.set(2999, 1, 1, 0, 0, 0);
        return calendar.getTime();
    }

    public static Timestamp now() {
        Calendar currDate = Calendar.getInstance();
        return new Timestamp((currDate.getTime()).getTime());
    }

    public static String getTimePast(long beginAt) {
        long completeAt = System.currentTimeMillis();
        long interval = completeAt - beginAt;
        long second = interval / 1000;
        long minute = 0;
        long hour = 0;
        String timeStr = second + "s";
        if (second >= 60) {
            minute = second / 60;
            second = second % 60;
            timeStr = minute + "m " + second + "s";
        }
        if (minute >= 60) {
            hour = minute / 60;
            minute = minute % 60;
            timeStr = hour + "h " + minute + "m " + second + "s";
        }

        return timeStr;
    }

    public static Date getLastSatOfThisMonth() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 3);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        cal.add(Calendar.DAY_OF_YEAR, -1);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);

        while (dayOfWeek != Calendar.SATURDAY) {
            cal.add(Calendar.DAY_OF_YEAR, -1);
            dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        }

        return cal.getTime();
    }

    // Time A
    public static Date get3DayBeforeLastSatOfThisMonth() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getLastSatOfThisMonth());
        cal.add(Calendar.DAY_OF_YEAR, -3);
        return cal.getTime();
    }

    public static Date getLastSatOfLastMonth() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 3);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        cal.add(Calendar.DAY_OF_YEAR, -1);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);

        while (dayOfWeek != Calendar.SATURDAY) {
            cal.add(Calendar.DAY_OF_YEAR, -1);
            dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        }

        return cal.getTime();
    }

    public static Double roundDouble(double val, int precision) {
        Double ret = null;
        try {
            double factor = Math.pow(10, precision);
            ret = Math.floor(val * factor + 0.5) / factor;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ret;
    }

    public final static String toYyMmdd(Date aDate) {
        if (aDate == null)
            return "";
        Calendar cal = new GregorianCalendar();
        cal.setTime(aDate);
        StringBuilder sb = new StringBuilder();
        int nYear = cal.get(Calendar.YEAR);
        nYear = nYear % 100;
        int nMonth = cal.get(Calendar.MONTH);
        nMonth++;
        int nDay = cal.get(Calendar.DAY_OF_MONTH);
        if (nYear < 10)
            sb.append('0');
        sb.append(nYear);
        if (nMonth < 10)
            sb.append('0');
        sb.append(nMonth);
        if (nDay < 10)
            sb.append('0');
        sb.append(nDay);
        return sb.toString();
    }

    public final static String toYyyymmddHhmmss(Date aDate) {
        if (aDate == null)
            return "";
        Calendar cal = new GregorianCalendar();
        cal.setTime(aDate);
        int nYear = cal.get(Calendar.YEAR);
        int nMonth = cal.get(Calendar.MONTH);
        nMonth++;
        int nDay = cal.get(Calendar.DAY_OF_MONTH);
        int nHour = cal.get(Calendar.HOUR_OF_DAY);
        int nMInute = cal.get(Calendar.MINUTE);
        int nSeconf = cal.get(Calendar.SECOND);

        StringBuilder sb = new StringBuilder();
        sb.append(nYear);
        sb.append('-');
        if (nMonth < 10)
            sb.append('0');
        sb.append(nMonth);
        sb.append('-');
        if (nDay < 10)
            sb.append('0');
        sb.append(nDay);

        sb.append(' ');

        if (nHour < 10)
            sb.append('0');
        sb.append(nHour);
        sb.append(':');
        if (nMInute < 10)
            sb.append('0');
        sb.append(nMInute);
        sb.append(':');
        if (nSeconf < 10)
            sb.append('0');
        sb.append(nSeconf);

        return sb.toString();
    }

    /**
     * 功能: 获取当前时间的秒数
     *
     * @return 当前时间的秒数
     */
    public static String time() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }

    /**
     * 功能：获取相对当前时间的N天
     *
     * @param n 如果是前几个小时，n传入负数，如果是后几个小时，n传入正数
     */
    public static String getPreNDay(int n) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, n);
        return sdf.format(cal.getTime());
    }

    /**
     * 功能：获取当前所在月的第一天
     */
    public static String getfirstDayOfMonth(String str) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(parseDateDayFormat(str));
        cal.set(Calendar.DAY_OF_MONTH, 1);// 本月第一天
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }

    /**
     * 功能：比较两个时间的大小
     *
     * @param date1
     * @param date2
     */
    public static int compareToDate(String date1, String date2) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date dt1 = df.parse(date1);
            Date dt2 = df.parse(date2);
            if (dt1.getTime() > dt2.getTime()) {
                return 0;
            } else if (dt1.getTime() < dt2.getTime()) {
                return 1;
            } else {
                return 2;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
            return 3;
        }
    }

    /**
     * 功能：获取某段日期的所有日期
     *
     * @param begin 开始日期
     * @param end   结束日期
     */
    public static String[] getAllDay(String begin, String end) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date dBegin = sdf.parse(begin);
            Date dEnd = sdf.parse(end);
            List<Date> resultList = findDates(dBegin, dEnd);
            if (resultList != null && resultList.size() > 0) {
                String[] result = new String[resultList.size()];
                for (int i = 0; i < resultList.size(); i++) {
                    result[i] = sdf.format(resultList.get(i));
                }
                return result;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 功能：获取某段日期的所有日期
     *
     * @param begin 开始日期
     * @param end   结束日期
     */
    public static List<Date> findDates(Date begin, Date end) {
        List<Date> lDate = new ArrayList<Date>();
        lDate.add(begin);

        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(begin);
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(end);

        while (end.after(calBegin.getTime())) { // 测试此日期是否在指定日期之后
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            lDate.add(calBegin.getTime());
        }
        return lDate;
    }

    public static Date stringToDate(String date, String format) {
        if (date == null) {
            return null;
        }
        DateFormat dateFormat = null;
        dateFormat = new SimpleDateFormat(format);
        Date day = null;
        try {
            day = dateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return day;
    }

    /**
     * 根据date，加N天
     *
     * @param date
     * @param day  天数
     * @return Date
     */
    public static Date addDay(Date date, int day) {
        if (null == date) {
            return null;
        }
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.add(Calendar.DATE, day);
        return cal.getTime();
    }

    /**
     * 在当前时间上增加指定小时
     *
     * @param date
     * @return
     */
    public static Date addHour(Date date, BigDecimal hour) {
        if (date != null && hour != null && hour.compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal seconds = new BigDecimal(60);
            BigDecimal sB = hour.multiply(seconds).multiply(seconds);// 转换为second=
            // itemTime*60*60
            sB = sB.setScale(0, RoundingMode.HALF_UP);
            int second = sB.intValue();
            return addSecond(date, second);
        }
        return date;
    }

    /**
     * 在当前时间上增加指定小时
     *
     * @param date
     * @return
     */
    public static Date addHour(Date date, int hour) {
        if (date != null && hour != 0) {
            Calendar endDate = Calendar.getInstance();
            endDate.setTime(date);
            endDate.add(Calendar.HOUR, hour);
            date = endDate.getTime();
        }
        return date;
    }

    /**
     * 在当前时间上增加指定分钟
     *
     * @param date
     * @return
     */
    public static Date addMinute(Date date, int minute) {
        if (date != null && minute != 0) {
            Calendar endDate = Calendar.getInstance();
            endDate.setTime(date);
            endDate.add(Calendar.MINUTE, minute);
            date = endDate.getTime();
        }
        return date;
    }

    /**
     * 在当前时间上增加指定秒数
     *
     * @param date
     * @param second
     * @return
     */
    public static Date addSecond(Date date, int second) {
        if (date != null && second != 0) {
            Calendar endDate = Calendar.getInstance();
            endDate.setTime(date);
            endDate.add(Calendar.SECOND, second);
            date = endDate.getTime();
        }
        return date;
    }

    /**
     * 判断time是否在now的n天之内
     *
     * @param time
     * @param now
     * @param n    正数表示在条件时间n天之后，负数表示在条件时间n天之前
     * @return
     */
    public static boolean belongDate(Date time, Date now, int n) {

        Calendar calendar = Calendar.getInstance(); // 得到日历
        calendar.setTime(now);// 把当前时间赋给日历
        calendar.add(Calendar.DAY_OF_MONTH, n);
        Date before7days = calendar.getTime(); // 得到n前的时间
        if (before7days.getTime() < time.getTime()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断time是否在from，to之内
     *
     * @param time 指定日期
     * @param from 开始日期
     * @param to   结束日期
     * @return
     */
    public static boolean belongCalendar(Date time, Date from, Date to) {
        Calendar date = Calendar.getInstance();
        date.setTime(time);

        Calendar after = Calendar.getInstance();
        after.setTime(from);

        Calendar before = Calendar.getInstance();
        before.setTime(to);

        if (date.after(after) && date.before(before)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @param nowDate   要比较的时间
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return true在时间段内，false不在时间段内
     * @throws Exception
     */
    public static boolean hourMinuteBetween(String nowDate, String startDate, String endDate) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now = format.parse(nowDate);
        Date start = format.parse(startDate);
        Date end = format.parse(endDate);
        long nowTime = now.getTime();
        long startTime = start.getTime();
        long endTime = end.getTime();

        return nowTime >= startTime && nowTime <= endTime;
    }

    public static Date getStartTime(Date dateTime) {
        Calendar todayStart = Calendar.getInstance();
        todayStart.setTime(dateTime);
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    public static Date getEndTime(Date dateTime) {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.setTime(dateTime);
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    /**
     * 把日期时间格式化为指定格式，如：yyyy-MM-dd HH:mm
     *
     * @param dt         java.util.Date
     * @param formatType : 指定日期转化格式字符串模板,例如:yyyy-MM-dd
     * @return 格式化后的日期时间字符串
     */
    public static String formatDateTime(Date dt, String formatType) {
        String newDate = "";
        if (dt != null) {
            Locale locale = Locale.CHINESE;
            SimpleDateFormat dateStyle = new SimpleDateFormat(formatType, locale);
            newDate = dateStyle.format(dt);
        }
        return newDate;
    }

    /**
     * 根据传入格式与日期返回日期类型
     */
    public static Date getDateByStr(String format, String date) {
        if (StringUtils.isBlank(date)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(format);
        try {
            return df.parse(date);
        } catch (ParseException e) {
            e.fillInStackTrace();
            return null;
        }
    }

    /**
     * 校验时间格式是否是需要的格式
     *
     * @param date
     * @param format
     * @return
     */
    public static boolean checkDateFormater(String date, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date tmpDate = sdf.parse(date);
            return date.equals(sdf.format(tmpDate));
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 获取2个时间间隔秒
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static long getDateMarginSecond(Date beginDate, Date endDate) {
        long margin = 0;
        margin = endDate.getTime() - beginDate.getTime();
        margin = margin / 1000;
        return margin;
    }

    /**
     * 根据传入格式与日期与增加天数返回日期类型
     */
    public static Date getDateByadd(Date date, int add) {
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, add);
        } catch (Exception e) {
            e.fillInStackTrace();
        }
        return calendar.getTime();
    }

    /**
     * 当前格式化时间 yyyy-MM-dd HH:mm:ss
     */
    public static String getCurrentDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }

    /**
     * 获取当年的第一天
     */
    public static Date getCurrYearFirst() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }

    /**
     * 当前季度的开始时间
     * @return
     */
    public static Date getCurrentQuarterStartTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3)
                c.set(Calendar.MONTH, 0);
            else if (currentMonth >= 4 && currentMonth <= 6)
                c.set(Calendar.MONTH, 3);
            else if (currentMonth >= 7 && currentMonth <= 9)
                c.set(Calendar.MONTH, 4);
            else if (currentMonth >= 10 && currentMonth <= 12)
                c.set(Calendar.MONTH, 9);
            c.set(Calendar.DATE, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前季度的结束时间。即2012-03-31 23:59:59
     *
     * @return
     */
    public static Date getCurrentQuarterEndTime() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getCurrentQuarterStartTime());
        cal.add(Calendar.MONTH, 3);
        cal.add(Calendar.SECOND, -1);
        return cal.getTime();
    }

    /**
     * 获得当月1号零时零分零秒
     * @return
     */
    public static Date initDateByMonth(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     *  获取今日凌晨的13位时间戳
     */
    public static Long getTodayZeroPointTimestamps() {
        Long currentTimestamps = System.currentTimeMillis();
        Long oneDayTimestamps = Long.valueOf(60 * 60 * 24 * 1000);
        return currentTimestamps - (currentTimestamps + 60 * 60 * 8 * 1000) % oneDayTimestamps;
    }


    /**
     * 获取某年第一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }


    /**
     * 功能: 获得当前周- 周一的日期 周一的00:00:00
     */
    public static Date getNowWeekBegin() {
        int mondayPlus;
        Calendar cd = Calendar.getInstance();
        // 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
        if (dayOfWeek == 1) {
            mondayPlus = 0;
        } else {
            mondayPlus = 1 - dayOfWeek;
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        Date monday = currentDate.getTime();
        monday = DateUtils.truncate(monday, Calendar.DATE);
        return monday;
    }
    /**
     * 获得当前周 周日的日期字符串
     * yyyy-MM-dd
     */
    public static String getSundayOfThisWeek() {
        Calendar c = Calendar.getInstance();
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) {
            day_of_week = 7;
        }
        c.add(Calendar.DATE, -day_of_week + 7);
        return new SimpleDateFormat("YYYY-MM-dd").format(c.getTime());
    }

    /**
     * 功能: 获得当前周- 周一的日期
     */
    public static int getMondayPlus() {
        Calendar cd = Calendar.getInstance();
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 1) {
            return -6;
        } else {
            return 2 - dayOfWeek;
        }
    }

    /**
     * 求两个日期相差小时数
     *
     * @param beginDate 开始日期
     * @param endDate   结束日期
     * @return 两个日期相差小时数
     */
    public static long getDateMarginWithHour(Date beginDate, Date endDate) {
        return getDateMarginWithMinute(beginDate, endDate) / 60;
    }

    /**
     * 求两个日期相差分钟数
     *
     * @param beginDate 开始日期
     * @param endDate   结束日期
     * @return 两个日期相差小时数
     */
    public static long getDateMarginWithMinute(Date beginDate, Date endDate) {
        return (endDate.getTime() - beginDate.getTime()) / (1000 * 60);
    }

    /**
     * 功能：获取当前时间本周的第一天
     */
    public static String getThisWeekFirstDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(cal.getTime());
    }

    /**
     * 功能: 获取当前时间剩余的秒数
     */
    public static long getRemainSecondsOneDay(Date currentDate) {
        LocalDateTime midnight = LocalDateTime.ofInstant(currentDate.toInstant(), ZoneId.systemDefault()).plusDays(1)
                .withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(), ZoneId.systemDefault());
        return ChronoUnit.SECONDS.between(currentDateTime, midnight);
    }

    /**
     * 功能: 获取当前时间剩余的分钟
     */
    public static long getRemainMinuteOneDay(Date currentDate) {
        LocalDateTime midnight = LocalDateTime.ofInstant(currentDate.toInstant(), ZoneId.systemDefault()).plusDays(1)
                .withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(), ZoneId.systemDefault());
        return ChronoUnit.MINUTES.between(currentDateTime, midnight);
    }

    /**
     * 功能: 获取当前时间剩余的小时
     */
    public static long getRemainHoursOneDay(Date currentDate) {
        LocalDateTime midnight = LocalDateTime.ofInstant(currentDate.toInstant(), ZoneId.systemDefault()).plusDays(1)
                .withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(), ZoneId.systemDefault());
        return ChronoUnit.HOURS.between(currentDateTime, midnight);
    }

    /**
     * 时间戳转换成时间
     *
     * @param lt 传入的时间戳 如果是10位时间戳
     * @return 返回格式化时间
     */
    public static String timeStampToTime(Integer lt) {
        if(lt==null || lt == 0){
            return "";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatDefaultTimestamp);
        Date date = new Date(Long.valueOf(lt) * 1000);
        String res = simpleDateFormat.format(date);
        return res;
    }

    /**
     * 获取时间周几 返回周一到周日的英语
     * @param str 时间 yyyy-MM-dd
     * @return
     */
    public static String getWeekday(String str) {
        Date date = parseDateDayFormat(str);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int result = (c.get(Calendar.DAY_OF_WEEK) == 1) ? 7 : (c.get(Calendar.DAY_OF_WEEK) - 1);
        switch (result) {
            case 1:
                return "monday";
            case 2:
                return "tuesday";
            case 3:
                return "wednesday";
            case 4:
                return "thursday";
            case 5:
                return "friday";
            case 6:
                return "saturday";
            case 7:
                return "sunday";
            default:
                return "未知";
        }
    }

    /**
     * 获取本月开始日期
     * @return String
     * **/
    public static String getMonthStart(){
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 00:00:00";
    }
    /**
     * 获取本月最后一天
     * @return String
     * **/
    public static String getMonthEnd(){
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 23:59:59";
    }
    /**
     * 获取本周的第一天
     * @return String
     * **/
    public static String getWeekStart(){
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.WEEK_OF_MONTH, 0);
        cal.set(Calendar.DAY_OF_WEEK, 2);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 00:00:00";
    }
    /**
     * 获取本周的最后一天
     * @return String
     * **/
    public static String getWeekEnd(){
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
        cal.add(Calendar.DAY_OF_WEEK, 1);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 23:59:59";
    }
    /**
     * 获取本年的第一天
     * @return String
     * **/
    public static String getYearStart(){
        return new SimpleDateFormat("yyyy").format(new Date())+"-01-01 00:00:00";
    }

    /**
     * 获取本年的最后一天
     * @return String
     * **/
    public static String getYearEnd(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH,calendar.getActualMaximum(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date currYearLast = calendar.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(currYearLast)+" 23:59:59";
    }

    /**
     * 今天起始时间
     * @return
     */
    public static String getDaysStart() {
        SimpleDateFormat sdf  =  new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(new Date())+" 00:00:00";
    }

    /**
     * 今天结束时间
     * @return
     */
    public static String getDaysEnd() {
        SimpleDateFormat sdf  =  new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(new Date())+" 23:59:59";
    }

    /**
     *  今天以前 n 天
     * @param n
     * @return
     */
    public static String yesterday(int n){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE,n); //当前 往前n天,n天以前
        Date date = calendar.getTime();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.format(date);
    }

    /**
     * 指定日期往前 n 天
     * @param n
     * @param day
     * @return
     */
    public static String removeDay(int n,String day){
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date =sdf.parse(day);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day1 = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day1-n);
       return  sdf.format(c.getTime());

    }
}